package it.uniroma2.art.coda.imdb;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DownloadIMDBPages {

	private static Logger logger = LoggerFactory.getLogger(DownloadIMDBPages.class);

	private String imdbListFilePath = "imdbList.txt";
	private String imdbDownloadedDirPath = "inputFiles";

	public static void main(String args[]) {
		DownloadIMDBPages donwloadedImdbPages = new DownloadIMDBPages();

		long start = System.currentTimeMillis();
		try {
			List<String> imdbList = donwloadedImdbPages.parseImdbListFile();
			logger.info("there are " + imdbList.size() + " imdb movies pages");
			for (int cont = 0; cont < imdbList.size(); ++cont) {
				String imdbPageUrl = imdbList.get(cont);
				logger.info((cont + 1) + " of " + imdbList.size() + ": requestin page: " + imdbPageUrl);
				String pageContent = donwloadedImdbPages.getTextOfPage(imdbPageUrl);
				if (pageContent.compareTo("") == 0) {
					if (cont == imdbList.size() - 1)
						Thread.sleep(1000);
					imdbList.add(imdbPageUrl);
					logger.info("Problem with page: " + imdbPageUrl);
				} else {
					donwloadedImdbPages.saveImdbPageContent(imdbPageUrl, pageContent);
				}
			}
		} catch (GenericTestException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			long end = System.currentTimeMillis();
			String prettyTime = "Program terminated after " + donwloadedImdbPages.printPrettyTime(start, end);
			logger.info(prettyTime);
		}
	}

	public List<String> parseImdbListFile() throws GenericTestException {
		List<String> imdbList = new ArrayList<String>();
		try {

			File file = new File(imdbListFilePath);
			BufferedReader bf = new BufferedReader(new FileReader(file));
			String line;
			while ((line = bf.readLine()) != null) {
				if (!line.startsWith("http"))
					continue;
				imdbList.add(line);
				imdbList.add(line + "fullcredits#cast");
			}
		} catch (FileNotFoundException e) {
			throw new GenericTestException(e);
		} catch (IOException e) {
			throw new GenericTestException(e);
		}

		return imdbList;
	}

	private String getTextOfPage(String htmlFilePath) throws IOException {
		// read the input file containig the test to be analized
		HttpURLConnection httpcon = null;
		StringBuilder contents = new StringBuilder();
		try {
			logger.debug("requesting imdb page");
			URL url = new URL(htmlFilePath);
			httpcon = (HttpURLConnection) url.openConnection();
			httpcon.setRequestMethod("GET");
			httpcon.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");

			httpcon.setDoOutput(true);
			httpcon.setConnectTimeout(10 * 1000);
			httpcon.setReadTimeout(10 * 1000);
			httpcon.connect();

			InputStreamReader inputStreamReader = new InputStreamReader(httpcon.getInputStream());
			BufferedReader br = new BufferedReader(inputStreamReader);

			// contents = new StringBuilder();
			String line;

			while ((line = br.readLine()) != null) {
				contents.append(line);
				contents.append(System.getProperty("line.separator"));
			}
		} catch (MalformedURLException e) {
			contents.delete(0, contents.length());
			contents.append("");
			logger.debug("MalformedURLException with: " + htmlFilePath);
			// e.printStackTrace();
		} catch (ProtocolException e) {
			contents.delete(0, contents.length());
			contents.append("");
			logger.debug("ProtocolException with: " + htmlFilePath);
			// e.printStackTrace();
		} catch (IOException e) {
			contents.delete(0, contents.length());
			contents.append("");
			logger.debug("IOException with: " + htmlFilePath);
			// e.printStackTrace();
		} finally {
			// close the connection, set all objects to null
			httpcon.disconnect();
			httpcon.setRequestProperty("Connection", "close");
		}
		logger.debug("imdb page obtained");
		if (contents.toString().compareTo("") == 0) {
			logger.debug("the imdb page " + htmlFilePath + " content is null");
			return "";
		}
		return contents.toString();
	}

	private void saveImdbPageContent(String imdbPageUrl, String imdbPageContent) throws IOException {
		String fileName = imdbPageUrl.substring(26, 35);
		if (imdbPageUrl.endsWith("fullcredits#cast")) {
			fileName += "_cast";
		}
		fileName += ".html";

		String completeFilePath = imdbDownloadedDirPath + System.getProperty("file.separator") + fileName;

		logger.info("saving page " + imdbPageUrl + " to " + completeFilePath);

		BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(completeFilePath));
		bufferedWriter.write(imdbPageContent);
		bufferedWriter.close();
	}

	public String printPrettyTime(long start, long end) {
		long secTotal = (end - start) / 1000;
		long sec = secTotal % 60;
		long minTotal = secTotal / 60;
		long min = minTotal % 60;
		long hourTotal = minTotal / 60;

		String prettyTime = "";
		if (hourTotal < 10)
			prettyTime += "0";
		prettyTime += hourTotal + ":";
		if (min < 10)
			prettyTime += "0";
		prettyTime += min + ":";
		if (sec < 10)
			prettyTime += "0";
		prettyTime += sec;

		return prettyTime;
	}
}
